#!/usr/bin/env python
# -*- coding: utf-8 -*-

import asyncio
import subprocess
from pathlib import Path
from typing import List, Optional, Tuple
import logging
import uuid

from .base_converter import BaseConverter, FileInfo

logger = logging.getLogger(__name__)

class PPTConverter(BaseConverter):
    """PPT转换器"""
    
    # 必需依赖应该为空，docling应该是可选的
    REQUIRED_DEPENDENCIES = {}

    OPTIONAL_DEPENDENCIES = {
        'pptx2md': 'pptx2md',  # 专业PPT转换工具（首选）
        'docling': 'docling'   # 通用文档转换工具
    }
    
    def __init__(self, temp_dir: Path, file_id: Optional[str] = None):
        super().__init__(temp_dir, file_id)
        self.default_method = self._get_default_method()
    
    def _get_default_method(self) -> str:
        """获取默认转换方法"""
        # 优先级：pptx2md > docling
        for method in ['pptx2md', 'docling']:
            if self.is_dependency_available(method):
                return method
        
        # 如果都不可用，返回pptx2md作为默认值（会在实际使用时报错）
        return 'pptx2md'
    
    async def convert(self, file_path: Path, method: Optional[str] = None, **kwargs) -> Tuple[str, List[FileInfo]]:
        """
        转换PPT文件
        
        Args:
            file_path: PPT文件路径
            method: 转换方法 ('docling', 'python-pptx')
            **kwargs: 其他参数
            
        Returns:
            tuple: (markdown内容, 文件信息列表)
        """
        method = method or self.default_method
        
        logger.info(f"使用 {method} 转换PPT: {file_path.name}")
        
        # 检查方法是否可用
        if not self.is_dependency_available(method):
            available_methods = self.get_available_methods()
            if available_methods:
                fallback_method = available_methods[0]
                logger.warning(f"{method} 不可用，使用 {fallback_method} 作为替代")
                method = fallback_method
            else:
                raise ImportError(
                    f"没有可用的PPT转换器。请安装以下任一依赖：\n"
                    f"- pptx2md (推荐): pip install pptx2md\n"
                    f"- docling: pip install docling"
                )
        
        if method == 'pptx2md':
            return await self._convert_with_pptx2md(file_path, **kwargs)
        elif method == 'docling':
            return await self._convert_with_docling(file_path, **kwargs)
        else:
            raise ValueError(f"不支持的转换方法: {method}。支持的方法: pptx2md, docling")
    
    async def _convert_with_pptx2md(self, file_path: Path, **kwargs) -> Tuple[str, List[FileInfo]]:
        """使用pptx2md转换PPT - 专业PPT转Markdown工具"""
        self.require_dependency('pptx2md', 'pptx2md')
        
        try:
            # 动态导入pptx2md
            from pptx2md import convert, ConversionConfig  # type: ignore
            
            logger.info("使用pptx2md转换PPT文件")
            
            # 创建输出目录
            output_dir = self.converter_work_dir / "pptx2md_output"
            output_dir.mkdir(exist_ok=True)
            
            # 创建图片目录
            image_dir = output_dir / "images"
            image_dir.mkdir(exist_ok=True)
            
            # 设置输出文件路径
            output_md = output_dir / f"{file_path.stem}.md"
            
            # 在线程池中执行转换（避免阻塞）
            loop = asyncio.get_event_loop()
            
            def run_conversion():
                try:
                    config = ConversionConfig(
                        pptx_path=file_path,
                        output_path=output_md,
                        image_dir=image_dir,
                        disable_notes=kwargs.get('disable_notes', True),
                        # disable_image=kwargs.get('disable_image', False),
                        # image_width=kwargs.get('image_width', None),
                        # min_block_size=kwargs.get('min_block_size', 20)
                    )
                    
                    convert(config)
                    
                    # 读取生成的markdown内容
                    if output_md.exists():
                        return output_md.read_text(encoding='utf-8')
                    else:
                        return f"# PPT转换结果\n\n**文件名**: {file_path.name}\n\n**转换工具**: pptx2md\n\n**说明**: 转换完成但未生成markdown文件"
                        
                except Exception as e:
                    logger.error(f"pptx2md转换过程出错: {e}")
                    return f"# PPT转换错误\n\n**文件名**: {file_path.name}\n\n**转换工具**: pptx2md\n\n**错误**: {str(e)}"
            
            markdown_content = await loop.run_in_executor(None, run_conversion)
            
            # 收集文件信息
            file_infos = []
            
            # 添加主文档信息
            doc_file_info = self.create_file_info(file_path, str(uuid.uuid4()), "document")
            file_infos.append(doc_file_info)
            
            # 添加生成的markdown文件信息
            if output_md.exists():
                md_file_info = self.create_file_info(output_md, str(uuid.uuid4()), "document")
                file_infos.append(md_file_info)
            
            # 使用基类方法收集生成的图片文件
            if image_dir.exists():
                generated_files = self.collect_generated_files(image_dir, ['*.png', '*.jpg', '*.jpeg', '*.gif', '*.bmp'])
                file_infos.extend(generated_files)
            
            logger.info(f"pptx2md转换完成: {len(file_infos)} 个文件")
            return markdown_content, file_infos
            
        except ImportError as e:
            logger.error(f"pptx2md导入失败: {e}")
            raise ImportError(f"pptx2md导入失败，请确认已正确安装: pip install pptx2md")
        except Exception as e:
            logger.error(f"pptx2md转换失败: {e}")
            # 提供基础回退方案
            markdown_content = f"# PPT文档\n\n**文件名**: {file_path.name}\n\n**说明**: pptx2md转换失败: {str(e)}"
            
            file_infos = []
            doc_file_info = self.create_file_info(file_path, str(uuid.uuid4()), "document")
            file_infos.append(doc_file_info)
            
            return markdown_content, file_infos
    
    async def _convert_with_docling(self, file_path: Path, **kwargs) -> Tuple[str, List[FileInfo]]:
        """使用docling转换PPT文件 - 使用基类的通用方法"""
        logger.info(f"使用docling转换PPT文件: {file_path.name}")
        return await self.convert_with_docling(file_path, **kwargs)
    

    

    
    def get_available_methods(self) -> List[str]:
        """获取可用的转换方法"""
        methods = []
        for method in ['pptx2md', 'docling']:
            if self.is_dependency_available(method):
                methods.append(method)
        return methods 